<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>AssortedWidgets</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:title" content="AssortedWidgets">
    <meta name="twitter:description" content="AssortedWidgets, an OpenGL GUI in WebAssembly!">
    <meta name="twitter:image" content="https://github.com/shi-yan/AssortedWidgets/raw/master/docs/screenshot.png">
    <link rel="stylesheet" href="css/bootstrap.css" media="screen">
    <link rel="stylesheet" href="css/blueimp-gallery.min.css">
    <link rel="stylesheet" href="css/atelier-forest-dark.css">
    <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.10.0/highlight.min.js"></script>
    <script>hljs.initHighlightingOnLoad();</script>

    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="../bower_components/html5shiv/dist/html5shiv.js"></script>
      <script src="../bower_components/respond/dest/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <div class="navbar navbar-default navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <a href="./" class="navbar-brand">AssortedWidgets</a>
        </div>
        <div class="navbar-collapse collapse" id="navbar-main">
          <ul class="nav navbar-nav navbar-right">
            <li><a href="https://github.com/shi-yan/AssortedWidgets" target="_blank">GitHub</a></li>
          </ul>

        </div>
      </div>
    </div>


    <div class="container">

      <div class="page-header" id="banner">
        <div class="row">
          <div class="col-lg-3 col-md-3 col-sm-4">
            <br />
          </div>
        </div>
        <div class="row">
          <div class="col-lg-3 col-md-3 col-sm-4">
            <div class="bs-component">
              <blockquote>
                <p>
                <cite>AssortedWidgets</cite> is an easy to use and lightweight ui library developed in C++11 and OpenGL ES 2. 
                <cite>AssortedWidgets</cite> can be built into <a href="http://webassembly.org/">WebAssembly</a> to run on the web. Try the live demo on this page!</p>
              </blockquote>
            </div>
            
            <div class="list-group table-of-contents">
              <a class="list-group-item" href="#Build">Build</a>
              <a class="list-group-item" href="#Usage">Usage</a>
              <a class="list-group-item" href="#Screenshots">Screenshots</a>
            </div>

            <!-- AddToAny BEGIN -->
            <div class="a2a_kit a2a_kit_size_32 a2a_default_style">
              <a class="a2a_dd" href="https://www.addtoany.com/share"></a>
              <a class="a2a_button_facebook"></a>
              <a class="a2a_button_twitter"></a>
              <a class="a2a_button_google_plus"></a>
              <a class="a2a_button_reddit"></a>
              <a class="a2a_button_linkedin"></a>
              <a class="a2a_button_hacker_news"></a>
            </div>
            <script async src="https://static.addtoany.com/menu/page.js"></script>
            <!-- AddToAny END -->
          </div>
          <div class="col-lg-1 col-md-1 col-sm-1">
          </div>
          <div class="col-lg-4 col-md-5 col-sm-6">

        <div id = "wasm" class="row">
          <figure style="overflow:visible;" id="spinner">
            <div class="spinner">
            </div>
          </figure>
          <div class="emscripten" id="status">Downloading...</div>
            <div class="emscripten">
              <progress value="0" max="100" id="progress" hidden=1></progress>  
            </div>
            <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
            <script type='text/javascript'>
                var statusElement = document.getElementById('status');
                var progressElement = document.getElementById('progress');
                var spinnerElement = document.getElementById('spinner');

                var Module = {
                  preRun: [],
                  postRun: [],
                  print: (function() {
                    return function(text) {
                      if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
                      // These replacements are necessary if you render to raw HTML
                      //text = text.replace(/&/g, "&amp;");
                      //text = text.replace(/</g, "&lt;");
                      //text = text.replace(/>/g, "&gt;");
                      //text = text.replace('\n', '<br>', 'g');
                      console.log(text);
                    };
                  })(),
                  printErr: function(text) {
                    if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
                    if (0) { // XXX disabled for safety typeof dump == 'function') {
                      dump(text + '\n'); // fast, straight to the real console
                    } else {
                      console.error(text);
                    }
                  },
                  canvas: (function() {
                  var canvas = document.getElementById('canvas');

                  // As a default initial behavior, pop up an alert when webgl context is lost. To make your
                  // application robust, you may want to override this behavior before shipping!
                  // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
                  canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);

                  return canvas;
                })(),
                setStatus: function(text) {
                  if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
                  if (text === Module.setStatus.text) return;
                  var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
                  var now = Date.now();
                  if (m && now - Date.now() < 30) return; // if this is a progress update, skip it if too soon
                  if (m) {
                    text = m[1];
                    progressElement.value = parseInt(m[2])*100;
                    progressElement.max = parseInt(m[4])*100;
                    progressElement.hidden = false;
                    spinnerElement.hidden = false;
                  } else {
                    progressElement.value = null;
                    progressElement.max = null;
                    progressElement.hidden = true;
                    if (!text) spinnerElement.hidden = true;
                }
                statusElement.innerHTML = text;
              },
            totalDependencies: 0,
            monitorRunDependencies: function(left) {
              this.totalDependencies = Math.max(this.totalDependencies, left);
              Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
          }
        };
        Module.setStatus('Downloading...');
        window.onerror = function() {
          Module.setStatus('Exception thrown (Your browswer may not support webassembly!), see JavaScript console');
          spinnerElement.style.display = 'none';
          Module.setStatus = function(text) {
            if (text) Module.printErr('[post-exception status] ' + text);
          };
        };
        </script>
        <script async type="text/javascript" src="AssortedWidgets.js"></script>
        </div>
          </div>
        </div>
      </div>


      <!-- Build
      ================================================== -->
      <div class="bs-docs-section">
        <div class="row">
          <div class="col-lg-12">
            <div class="page-header">
              <h1 id="Build">Build</h1>
            </div>
          </div>
        </div>

        <!-- Headings -->

        <div class="row">
          <div class="col-lg-4">
            <div class="bs-component">
              <h2>WebAssembly</h2>
              <p >1. Install <a href="http://webassembly.org/getting-started/developers-guide/">WebAssembly</a>.</p>
              <p >2. Under the <span class="text-warning">emsdk</span> folder, run <br/>
              <span class="text-warning">source ./emsdk_env.sh</span> </p>
              <p >3. Under the <span class="text-warning">AssortedWidgets</span> folder, run<br/> 
              <span class="text-warning">mkdir build<br/>
              cd build<br/>
              cmake .. -DCMAKE_TOOLCHAIN_FILE=~/AssortedWidgets/cmake/Modules/Emscripten.cmake<br/>
              make</span></p>
              <p >4. Once finished, run the following. You should be able to see AssortedWidgets in browser at <span class="text-warning">http://localhost:8080</span> <br/>
              <span class="text-warning">emrun --no_browser --port 8080 .</span> </p>
            </div>

          </div>
          <div class="col-lg-4">
            <div class="bs-component">
              <h2>Linux</h2>
              <p>1. Install SDL2 and SDL2_image: <br/> <span class="text-warning">sudo apt-get install libsdl2-dev ibsdl2-image-dev</span></p>
              <p>2. 2. Under AssortedWidgets folder, run <br/>
              <span class="text-warning">mkdir build<br/>
              cd build<br/>
              cmake ..<br/>
              make</span></p>
              <p>3. Once done, run<br/>
              <span class="text-warning">./AssortedWidgets</span>
              </p>
            </div>

          </div>
          <div class="col-lg-4">
            <div class="bs-component">
              <h2>Mac OS</h2>
              <p>1. Install SDL2 and SDL2_image via <a href="https://brew.sh/">homebrew</a>: <br/> <span class="text-warning">brew install sdl2 sdl2_image</span> </p>
              <p>2. 2. Under AssortedWidgets folder, run <br/>
              <span class="text-warning">mkdir build<br/>
              cd build<br/>
              cmake ..<br/>
              make</span></p>
              <p>3. Once done, run<br/>
              <span class="text-warning">./AssortedWidgets</span>
              </p>
            </div>

          </div>
        </div>
      </div>


     <!-- Usage
      ================================================== -->
      <div class="bs-docs-section">
        <div class="row">
          <div class="col-lg-12">
            <div class="page-header">
              <h1 id="Usage">Usage</h1>
            </div>
          </div>
        </div>

        <!-- Headings -->

        <div class="row">
          <div class="col-lg-12">
          <p> 
          To use AssortedWidgets, first define a class inherits <span class="text-warning">AssortedWidgets::Widgets::Dialog</span>:
          </p>
          <pre style="background-color: #1b1918; border: 0px;"><code class="c++">
          class DemoDialog: public AssortedWidgets::Widgets::Dialog
          {
          public:
              DemoDialog(void);
              ~DemoDialog(void);
          };
          </code></pre>
          <p>Then, add desired UI elements and layouts to the dialog as private members:</p>
          <pre style="background-color: #1b1918; border: 0px;"><code class="c++">
          class DemoDialog: public AssortedWidgets::Widgets::Dialog //subclass the common base for all dialogs.
          {
          private:
              Widgets::Button *m_closeButton;   //add a button
              Widgets::Label *m_label;          //add a text label
              Widgets::ScrollPanel *m_panel;    //add a scroll panel
              Layout::GridLayout *m_gridLayout; //a layout is a container of UI elements.
          public:
              DemoDialog(void);
          public:
              ~DemoDialog(void);
          };
          </code></pre>
          <p>Initialize the dialog in its constructor:</p>
          <pre style="background-color: #1b1918; border: 0px;"><code class="c++">
          DemoDialog::DemoDialog(void)
            :Dialog("Scroll Panel Test:",400,400,320,240) //provide dialog title and size.
          {
              m_gridLayout=new Layout::GridLayout(2,1); //initialize the grid layout, set its margin
              m_gridLayout->setRight(16);
              m_gridLayout->setLeft(16);
              m_gridLayout->setTop(8);
              m_gridLayout->setBottom(8);
              m_gridLayout->setSpacer(4);

              m_gridLayout->setHorizontalAlignment(1,0,Layout::GridLayout::HRight);

              m_closeButton=new Widgets::Button("Close"); //initialize the UI elements on this dialog
              m_label=new Widgets::Label("I am a very very big Label in a Scroll Panel.");
              m_label->m_size.m_height=m_label->m_size.m_width=500;
              m_panel=new Widgets::ScrollPanel();
              m_panel->setContent(m_label); //add the label to the scroll panel

              setLayout(m_gridLayout); //let this dialog to use this layout
              add(m_panel); //add both the scroll panel and the close button to the dialog
              add(m_closeButton);

              pack(); //this function update the sizes and locations of internal UI elements
          }
          </code></pre>
          <p>Go back to the class definition, add a <span class="text-warning">onClose()</span> function to handle the mouse release event of the close button:</p>
          <pre style="background-color: #1b1918; border: 0px;"><code class="c++">
          class DemoDialog: public AssortedWidgets::Widgets::Dialog
          {
          private:
              Widgets::Button *m_closeButton;
              Widgets::Label *m_label;
              Widgets::ScrollPanel *m_panel;
              Layout::GridLayout *m_gridLayout;
          public:
              void onClose(const Event::MouseEvent &e);
              DemoDialog(void);
              ~DemoDialog(void);
          };
          </code></pre>
          <p>Register the <span class="text-warning">onClose()</span> function as the handle of the mouse release event of the close button:</p>
          <pre style="background-color: #1b1918; border: 0px;"><code class="c++">
          DemoDialog::DemoDialog(void):Dialog("Scroll Panel Test:",400,400,320,240)
          {
              ...

              //register the onClose function as the event handler of the close button's mouse release event
              m_closeButton->mouseReleasedHandlerList.push_back(MOUSE_DELEGATE(DemoDialog::onClose));
          }

          void DemoDialog::onClose(const Event::MouseEvent &)
          {
              //this is the event handler, it calls a predefined function Close() to shut the dialog
              Close();
          }
          </code></pre>

          </div>

        </div>


      </div>

     <!-- Build
      ================================================== -->
      <div class="bs-docs-section">
        <div class="row">
          <div class="col-lg-12">
            <div class="page-header">
              <h1 id="Screenshots">Screenshots</h1>
            </div>
          </div>
        </div>

<div id="links" class="links" style="display: none;">
    <a href="https://github.com/shi-yan/AssortedWidgets/raw/master/docs/aw1.jpg" title="aw1">
        <img src="https://github.com/shi-yan/AssortedWidgets/raw/master/docs/aw1.jpg" alt="aw1">
    </a>
    <a href="https://github.com/shi-yan/AssortedWidgets/raw/master/docs/aw3.jpg" title="aw3">
        <img src="https://github.com/shi-yan/AssortedWidgets/raw/master/docs/aw3.jpg" alt="aw3">
    </a>
    <a href="https://github.com/shi-yan/AssortedWidgets/raw/master/docs/aw4.jpg" title="aw4">
        <img src="https://github.com/shi-yan/AssortedWidgets/raw/master/docs/aw4.jpg" alt="aw4">
    </a>
        <a href="https://github.com/shi-yan/AssortedWidgets/raw/master/docs/aw5.jpg" title="aw5">
        <img src="https://github.com/shi-yan/AssortedWidgets/raw/master/docs/aw5.jpg" alt="aw5">
    </a>
        <a href="https://github.com/shi-yan/AssortedWidgets/raw/master/docs/aw6.jpg" title="aw6">
        <img src="https://github.com/shi-yan/AssortedWidgets/raw/master/docs/aw6.jpg" alt="aw6">
    </a>
</div>

        <!-- Headings -->

        <div class="row">
          
<!-- The Gallery as inline carousel, can be positioned anywhere on the page -->
<div id="blueimp-gallery-carousel" class="blueimp-gallery blueimp-gallery-carousel">
    <div class="slides"></div>
    <h3 class="title"></h3>
    <a class="prev">‹</a>
    <a class="next">›</a>
    <a class="play-pause"></a>
    <ol class="indicator"></ol>
</div>
    <script src="js/blueimp-gallery.min.js"></script>

<script>
blueimp.Gallery(
    document.getElementById('links').getElementsByTagName('a'),
    {
        container: '#blueimp-gallery-carousel',
        carousel: true
    }
);
</script>

        </div>


      </div>


      <footer>
        <div class="row">
          <div class="col-lg-12">

            <ul class="list-unstyled">
              <li class="pull-right"><a href="#top">Back to top</a></li>
              <li><a href="https://medium.com/@shiyan">Blog</a></li>
            </ul>
            
            <p>Code released under the <a href="https://github.com/shi-yan/AssortedWidgets/blob/master/LICENSE">MIT License</a>.</p>
            <p>Based on <a href="http://getbootstrap.com" rel="nofollow">Bootstrap</a>. Icons from <a href="http://fortawesome.github.io/Font-Awesome/" rel="nofollow">Font Awesome</a>. Web fonts from <a href="http://www.google.com/webfonts" rel="nofollow">Google</a>.</p>

          </div>
        </div>

      </footer>


    </div>
    <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
  </body>
</html>
